package com.hiultra.archive.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hiultra.archive.domain.*;
import com.hiultra.archive.domain.vo.ArchiveDesTaskIssuedVo;
import com.hiultra.archive.domain.vo.ArchiveStorageTaskIssuedVo;
import com.hiultra.archive.domain.vo.ArchiveStorageTaskReportVo;
import com.hiultra.archive.domain.vo.ResultEntity;
import com.hiultra.archive.mapper.*;
import com.hiultra.archive.service.IArchiveStorageService;
import com.hiultra.archive.service.IArchiveStorageTaskService;
import com.hiultra.archive.service.IRoomArchiveService;
import com.hiultra.archive.utils.sgsm.SM2Util;
import com.hiultra.archive.utils.tool.ToolUtils;
import com.hiultra.common.constant.BusinessConstants;
import com.hiultra.common.exception.ServiceException;
import com.hiultra.common.utils.DateUtils;
import com.hiultra.common.utils.SecurityUtils;
import com.hiultra.common.utils.uuid.UUID;
import org.junit.jupiter.api.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 档案入库任务Service业务层处理
 *
 * @author ruoyi
 * @date 2024-07-22
 */
@Service
public class ArchiveStorageTaskServiceImpl implements IArchiveStorageTaskService {

    private static final Logger log = LoggerFactory.getLogger(ArchiveStorageTaskServiceImpl.class);

    @Autowired
    private ArchiveStorageTaskMapper archiveStorageTaskMapper;

    @Autowired
    private ArchiveStorageMapper archiveStorageMapper;

    @Autowired
    private ArchiveBoxStatusMapper archiveBoxStatusMapper;

    @Autowired
    private IArchiveStorageService archiveStorageService;

    @Autowired
    private IArchiveStorageTaskService archiveStorageTaskService;

    @Autowired
    private IRoomArchiveService roomArchiveService;

    @Autowired
    private ArcBoxMapper arcBoxMapper;

    @Value("${priKey}")
    private String priKey;

    /**
     * 查询档案入库任务
     *
     * @param taskId 档案入库任务主键
     * @return 档案入库任务
     */
    @Override
    public ArchiveStorageTask selectArchiveStorageTaskByTaskId(String taskId) {
        return archiveStorageTaskMapper.selectArchiveStorageTaskByTaskId(taskId);
    }

    /**
     * 通过任务单号查询档案入库任务
     *
     * @param warehousingNo 档案入库任务主键
     * @return 档案入库任务
     */
    @Override
    public ArchiveStorageTask selectArchiveStorageTaskByTaskNo(String warehousingNo) {
        return archiveStorageTaskMapper.selectArchiveStorageTaskByTaskNo(warehousingNo);
    }

    /**
     * 查询档案入库任务列表
     *
     * @param archiveStorageTask 档案入库任务
     * @return 档案入库任务
     */
    @Override
    public List<ArchiveStorageTask> selectArchiveStorageTaskList(ArchiveStorageTask archiveStorageTask) {
        return archiveStorageTaskMapper.selectArchiveStorageTaskList(archiveStorageTask);
    }

    /**
     * 新增档案入库任务
     *
     * @param archiveStorageTask 档案入库任务
     * @return 结果
     */
    @Override
    public int insertArchiveStorageTask(ArchiveStorageTask archiveStorageTask) {
        archiveStorageTask.setCreateTime(DateUtils.getNowDate());
        return archiveStorageTaskMapper.insertArchiveStorageTask(archiveStorageTask);
    }

    /**
     * 修改档案入库任务
     *
     * @param archiveStorageTask 档案入库任务
     * @return 结果
     */
    @Override
    @Transactional
    public int updateArchiveStorageTask(ArchiveStorageTask archiveStorageTask) {
        //设置入库任务状态和时间
        archiveStorageTask.setWarehousingTime(DateUtils.getNowDate());
        archiveStorageTask.setWarehousingResult(BusinessConstants.WAREHOUSING_RESULT_SUCCESS);
        archiveStorageTask.setStatus(BusinessConstants.IN_STATUS_END);
        archiveStorageTask.setWarehousingBy(SecurityUtils.getLoginUser().getUser().getCustNo());

        //新增盒状态表
        List<ArchiveStorage> archiveStorages = archiveStorageMapper.selectArchiveStorageByTaskId(archiveStorageTask.getTaskId());
        for (ArchiveStorage archiveStorage : archiveStorages) {
            //根据档案盒id 查询档案盒信息
            ArcBox arcBox = arcBoxMapper.selectArcBoxByBoxId(archiveStorage.getBoxId());
            //判空
            if (ObjectUtil.isEmpty(arcBox)) {
                throw new ServiceException("未查询到档案盒标识为" + archiveStorage.getBoxId() + "的信息，请检查重试！");
            }
            ArchiveBoxStatus archiveBoxStatus = new ArchiveBoxStatus();
            archiveBoxStatus.setAreaNo(arcBox.getAreaNo());
            archiveBoxStatus.setCabinetNo(arcBox.getCabinetNo());
            archiveBoxStatus.setBoxBarCode(arcBox.getBoxRfid());
            archiveBoxStatus.setBoxNo(arcBox.getBoxCode());
            archiveBoxStatus.setHouseLocationNo(arcBox.getHouseLocationNo());

            archiveBoxStatus.setBoxStatus(BusinessConstants.ARC_STOCK);
            archiveBoxStatus.setRecordTime(DateUtils.getNowDate());
            archiveBoxStatus.setPushStatus(BusinessConstants.PUSHSTATUS);

            //入库完成，需要修改档案盒在库状态为1
            arcBox.setInStockStatus(BusinessConstants.IN_STOCK_STATUS);
            arcBoxMapper.updateArcBox(arcBox);

            archiveBoxStatusMapper.insertArchiveBoxStatus(archiveBoxStatus);
        }

        return archiveStorageTaskMapper.updateArchiveStorageTask(archiveStorageTask);
    }

    /**
     * 批量删除档案入库任务
     *
     * @param taskIds 需要删除的档案入库任务主键
     * @return 结果
     */
    @Override
    public int deleteArchiveStorageTaskByTaskIds(String[] taskIds) {
        return archiveStorageTaskMapper.deleteArchiveStorageTaskByTaskIds(taskIds);
    }

    /**
     * 删除档案入库任务信息
     *
     * @param taskId 档案入库任务主键
     * @return 结果
     */
    @Override
    public int deleteArchiveStorageTaskByTaskId(String taskId) {
        return archiveStorageTaskMapper.deleteArchiveStorageTaskByTaskId(taskId);
    }

    /**
     * 批量新增入库任务
     */
    @Override
    public int batchInsertArchiveStorageTask(List<ArchiveStorageTask> archiveStorageTask) {
        if (ObjectUtil.isEmpty(archiveStorageTask)) {
            return 0;
        }
        return archiveStorageTaskMapper.batchInsertArchiveStorageTask(archiveStorageTask);
    }

    /**
     * 档案入库任务下发接口
     *
     * @param data
     * @return 结果
     */
    @Override
    public ResultEntity insertIssuedArchiveStorageTask(String data) {

        System.out.println("入库任务下发入参：" + data);
        //解密
        String decryptedResult = new SM2Util().decryptBySM2(data, priKey);
        System.out.println("入库任务下发解密结果：" + decryptedResult);
        ArchiveStorageTaskIssuedVo archiveStorageTaskIssuedVo = JSON.parseObject(decryptedResult.trim(), ArchiveStorageTaskIssuedVo.class);
        log.info("档案入库任务下发接口");

        if (ObjectUtil.isNull(archiveStorageTaskIssuedVo)) {
            // 返回错误信息或抛出异常
            log.info("入参解析出错，请检查重试");
            return ResultEntity.error("入参解析出错，请检查重试");
        }
        try {
            processArchiveStorageTask(archiveStorageTaskIssuedVo);
        } catch (ServiceException e) {
            e.printStackTrace();
            return ResultEntity.error(e.getMessage());
        }
        return ResultEntity.success();

    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void processArchiveStorageTask(ArchiveStorageTaskIssuedVo archiveStorageTaskIssuedVo) throws ServiceException {
        try {
            List<ArchiveStorageTask> archiveStorageTaskList = new ArrayList<>();
            List<ArchiveStorage> archiveStorageList = new ArrayList<>();
            List<RoomArchive> roomArchiveList = new ArrayList<>();

            if (ObjectUtil.isNotNull(archiveStorageTaskIssuedVo)) {
                ArchiveStorageTask archiveStorageTaskIs = archiveStorageTaskMapper.selectArchiveStorageTaskByTaskNo(archiveStorageTaskIssuedVo.getWarehousingNo());
                if (null == archiveStorageTaskIs) {
                    ArchiveStorageTask archiveStorageTask = ToolUtils.convertEntity(archiveStorageTaskIssuedVo, ArchiveStorageTask::new);
                    archiveStorageTask.setTaskId(UUID.randomUUID().toString().replace("-", ""));
                    archiveStorageTask.setPushStatus(BusinessConstants.PUSHSTATUS);
                    archiveStorageTask.setStatus(BusinessConstants.IN_STATUS_ING);
                    archiveStorageTaskList.add(archiveStorageTask);

                    List<ArchiveStorageTaskIssuedVo.Archive> archiveList = archiveStorageTaskIssuedVo.getArichiveList();

                    for (ArchiveStorageTaskIssuedVo.Archive archive : archiveList) {
                        if (ObjectUtil.isEmpty(archiveList)) {
                            continue;
                        }
                        ArchiveStorage archiveStorage = ToolUtils.convertEntity(archive, ArchiveStorage::new);
                        archiveStorage.setId(UUID.randomUUID().toString().replace("-", ""));
                        archiveStorage.setTaskId(archiveStorageTask.getTaskId());
                        archiveStorageList.add(archiveStorage);
                        //新增档案信息
                        RoomArchive roomArchive = ToolUtils.convertEntity(archive, RoomArchive::new);
                        roomArchive.setId(archive.getArchiveId());
                        //根据档案盒id查询档案盒no
                        ArcBox arcBox = arcBoxMapper.selectArcBoxByBoxId(archive.getBoxId());
                        //判空
                        if (ObjectUtil.isEmpty(arcBox)) {
                            log.info("档案盒标识" + archive.getBoxId() + "不存在,请检查重试！");
                            throw new ServiceException("档案盒标识" + archive.getBoxId() + "不存在,请检查重试！");
                        }
                        //设置借阅状态默认值
                        roomArchive.setGiveBackStatus(BusinessConstants.PRE_GIVE_BACK_STATUS);
                        roomArchive.setCabinetNo(arcBox.getCabinetNo());
                        roomArchive.setAreaNo(arcBox.getAreaNo());
                        roomArchive.setBoxNo(arcBox.getBoxCode());
                        roomArchive.setArchiveName(archive.getArchName());
                        roomArchive.setArchiveType(archive.getArchType());
                        roomArchive.setConLevel(archive.getConfdLv());
                        roomArchive.setSaveDate(archive.getKeepDur());
                        roomArchive.setDelflag(BusinessConstants.DELFLAG);
                        roomArchiveList.add(roomArchive);
                    }
                }
            }

            //批量插入数据
            archiveStorageTaskService.batchInsertArchiveStorageTask(archiveStorageTaskList);
            archiveStorageService.batchInsertArchiveStorage(archiveStorageList);
            roomArchiveService.batchInsertRoomArchive(roomArchiveList);
        } catch (ServiceException e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new ServiceException(e.getMessage());
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new ServiceException("发生未知异常，事务已回滚");
        }
    }

}
